package debug_integration;

import static org.junit.Assert.*;
import java.lang.reflect.Field;
import org.junit.Before;
import org.junit.Test;

import debug.apple_debug;
import blackjack.MyMath;

/* CPU METHOD SPECIFICATION
 * 1. 	The method simulate the cpu game.
 * 2.   The cpu hits until cpu_score < player_score.
 * 3.	The cpu hits until cpu_score < 17.
 * 4. 	The winner score is incremented by one.
 * 5.   In case of tie, the game ends and no score is incremented.
 * 6. 	In case of victory, defeat or tie, a specific message is shown.
 * 
 * TESTS SUMMARY
 *  TEST 01: player = 17 && randList = {13,8} 			needed cpu_score (18) > 17	 				RES: win (not busted)
 *	TEST 02: player = 16 && randList = {9,3,5} 			needed cpu_score = 17 						RES: win (not busted)
 *	TEST 03: player = 18 && randList = {8,1,5,11} 		'A' value is 11; no correction 				RES: win (not busted)
 *	TEST 04: player = 19 && randList = {1,5,10,4} 		'A' correction [already in set - 1st]		RES: win (not busted)
 *  TEST 05: player = 18 && randList = {1,1,8}			'A' correction [first 2 cards]				RES: win (not busted)
 *  TEST 06: player = 18 && randList = {12,4,7} 		cpu wins with blackjack 					RES: win (not busted)
 *  TEST 07: player = 14 && randList = {9,5,11} 		cpu loses passing for tie [tie_score < 17] 	RES: busted (not tie)
 *	TEST 08: player = 15 && randList = {7,9,10} 		needed cpu_score (16) < 17 					RES: busted (not win)
 * 	TEST 09: player = 17 && randList = {3,4,10,2} 		cpu ties with 17 							RES: tie (not win)
 *	TEST 10: player = 18 && randList = {12,7,1} 		cpu ties with 'A' [tie_score > 17] 			RES: tie (not busted)
 */

public class cpuTest {
	
	private apple_debug appleRef;
	//private apple_mod_correct appleRef;
	private Field player, state_player, state_cpu;
	
	@Before
	public void setUp() throws Exception {
		appleRef = new apple_debug();
		//appleRef = new apple_mod_correct();
		
		player = (appleRef.getClass()).getDeclaredField("player");
		player.setAccessible(true);
		
		state_player = (appleRef.getClass()).getDeclaredField("state_player");
		state_player.setAccessible(true);
		
		state_cpu = (appleRef.getClass()).getDeclaredField("state_cpu");
		state_cpu.setAccessible(true);
	}
	
	/* TEST 01: player = 17 && randList = {13,8}
	 * DESC: needed cpu_score (18) > 17 
	 * RES: win (not busted); reset cpu */
	@Test
	public void testCpu_01() throws Exception {
		// START preconditions
		double[] randList = {13,8};
		MyMath.set_randList(randList);
		player.setInt(appleRef,17);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 02: player = 16 && randList = {9,3,5}
	 * DESC: needed cpu_score = 17
	 * RES: win (not busted) */
	@Test
	public void testCpu_02() throws Exception {
		// START preconditions
		double[] randList = {9,3,5};
		MyMath.set_randList(randList);
		player.setInt(appleRef,16);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 03: player = 18 && randList = {8,1,5,11}
	 * DESC: 'A' value is 11 [no correction] 
	 * RES: win (not busted) */
	@Test
	public void testCpu_03() throws Exception {
		// START preconditions
		double[] randList = {8,1,5,11};
		MyMath.set_randList(randList);
		player.setInt(appleRef,18);
		// END preconditions

		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 04: player = 19 && randList = {1,5,10,4}
	 * DESC: 'A' correction [with 'A' already in set and 1st card]
	 * RES: win (not busted) */
	@Test
	public void testCpu_04() throws Exception {
		// START preconditions
		double[] randList = {1,5,10,4};
		MyMath.set_randList(randList);
		player.setInt(appleRef,19);
		// END preconditions

		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 05: player = 18 && randList = {1,1,8}
	 * DESC: 'A' correction [with 'A' already in set and 2nd card]
	 * RES: win (not busted) */
	@Test
	public void testCpu_05() throws Exception {
		// START preconditions
		double[] randList = {1,1,8};
		MyMath.set_randList(randList);
		player.setInt(appleRef,18);
		// END preconditions

		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 06: player = 18 && randList = {12,4,7} 
	 * DESC: cpu wins with blackjack
	 * RES: win (not busted) */
	@Test
	public void testCpu_06() throws Exception {
		// START preconditions
		double[] randList = {12,4,7};
		MyMath.set_randList(randList);
		player.setInt(appleRef,18);
		// END preconditions

		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();

		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu+1,state_cpu.getInt(appleRef));
	}
	
	/* TEST 07: player = 14 && randList = {9,5,11}
	 * DESC: cpu loses passing for tie [tie_score < 17]
	 * RES: lose (not tie) */
	@Test
	public void testCpu_07() throws Exception {
		// START preconditions
		double[] randList = {9,5,11};
		MyMath.set_randList(randList);
		player.setInt(appleRef,14);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player+1,state_player.getInt(appleRef));
		assertEquals(old_state_cpu,state_cpu.getInt(appleRef));
	}
	
	/* TEST 08: player = 15 && randList = {7,9,10} 
	 * DESC: needed cpu_score (16) < 17
	 * RES: busted (not win) */
	@Test
	public void testCpu_08() throws Exception {
		// START preconditions
		double[] randList = {7,9,10};
		MyMath.set_randList(randList);
		player.setInt(appleRef,15);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();

		assertEquals(old_state_player+1,state_player.getInt(appleRef));
		assertEquals(old_state_cpu,state_cpu.getInt(appleRef));
	}
	
	/* TEST 09: player = 17 && randList = {3,4,10,2}
	 * DESC: cpu ties with 17
	 * RES: tie (not win) */
	@Test
	public void testCpu_09() throws Exception {
		// START preconditions
		double[] randList = {3,4,10,2};
		MyMath.set_randList(randList);
		player.setInt(appleRef,17);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu,state_cpu.getInt(appleRef));
	}
	
	/* TEST 10: player = 18 && randList = {12,7,1}
	 * DESC: cpu ties with 'A' [tie_score > 17]
	 * RES: tie (not busted) */
	@Test
	public void testCpu_10() throws Exception {
		// START preconditions
		double[] randList = {12,7,1};
		MyMath.set_randList(randList);
		player.setInt(appleRef,18);
		// END preconditions
		
		int old_state_player = state_player.getInt(appleRef);
		int old_state_cpu = state_cpu.getInt(appleRef);
		
		appleRef.cpu();
		
		assertEquals(old_state_player,state_player.getInt(appleRef));
		assertEquals(old_state_cpu,state_cpu.getInt(appleRef));
	}

}